<!--
  功能：自定义一个表单，携带按钮，并且点击按钮可以自动获取表单内控件的值，提交后台，同时此表单组件还能接受其他组件嵌入

  难点：此表单组件 实际上是el-form的扩展，在嵌入布局器后，依然支持el-form-item子组件
  这就为我们代来了难点，出现嵌套情况十分烦恼，因为我们要遍历el-form内有哪些组件，然后遍历出来
  并且组装参数 提交后台

  收获：突破vue的固有编程限制，灵活判断组件内的子组件，这对我们写框架，通用组件很有帮助

  action:"" 提交表单的后台接受地址
  method:"" 提交表单的后端地址方法
  successMsg:"" 当提交成功 提示信息
  failMsg："" 当提交失败 提示信息

  dataUrl:"" 初始化时渲染数据的地址
  废弃，不好用，已被McQuestionaire取代
-->
<template>
  <el-form v-bind="$attrs" v-on="$listeners">
    <slot/>
    <el-button @click="submitForm">提交</el-button>
  </el-form>
</template>

<script>
export default {
    name: 'mc-form',
    data () {
        return {
        }
    },
    props: ['action','method','successMsg','failMsg','dataUrl'],
    mounted () {
          var request = this.$magicaltool.request;
          if(typeof vueData!='undefined' && this.dataUrl){
               request.axios({$vue:this,method:"get",url:this.dataUrl,params:{} })
               .then(function(response) {
                    var resData = response;
                    if(resData){
                        if(resData.code==0){
                            var data = resData.data;
                            if(data){
                                for(var key in data){
                                    if(typeof vueData[key]!='undefined'){
                                        vueData[key] = data[key];
                                    }
                                }
                            }
                        }
                    }
                }).catch(function (error) {
                    console.log(error)
                });
          }
    },
    methods:{
        //递归算法
        iteratorChildren:function(component,valueMap){
            var vnode =  component._self.$vnode;
            var data = vnode.data;
            // console.log(data)
            if(data['model']){//v-model藏得太深了 注意上传文件这里没搞 TODO
              valueMap[data.model.expression]=data.model.value;
            }
            var children = component.$children;
            if(children&& children.length>0){
                for(var i=0;i<children.length;i++){
                    this.iteratorChildren(children[i],valueMap);
                }
            }
        },
        submitForm:function(){
            var _t = this;
            var request = this.$magicaltool.request;

            //取form内的控件的v-model值，这些是绑定数据库字段的值 注意实际情况下 可能嵌套还要复杂 或许还有el-form-item 那就请自行debug看看children内的参数了 这里就不演示了 直接取el-form内的控件
            var children = this.$children[0].$children;
            var valueMap = {};
            for(var i=0;i<children.length;i++){
                var component = children[i];
                this.iteratorChildren(component,valueMap)
            }
            //下一步就简单了 拿到valueMap做入参 直接丢给后台api 请自行研究axios吧
            if(this.action){
                switch(this.method){
                    case 'post' :
                        request.axios({$vue:this,method:"post",url:this.action,data:valueMap,headers:{'content-type':'application/json','charset':'UTF-8'}}).then(function(response) {
                             _t.afterSubmit(response);
                        }).catch(function (error) {
                            console.log(error)
                        });
                        break;
                    default:
                        request.axios({$vue:this,method:"get",url:this.action,params:valueMap }).then(function(response) {
                                _t.afterSubmit(response);
                            }).catch(function (error) {
                                console.log(error)
                            });
                }
            }else{
                this.$message("请配置请求地址action");
            }
        },
        afterSubmit:function(data){
            if(data){
                if(typeof res['code']!== 'undefined' && res.code===0){
                    if(this.successMsg){
                        this.$message(this.successMsg);
                    }
                }else{
                    if(data['msg']){
                        this.$message(data.msg);
                    }else{
                        if(this.failMsg){
                            this.$message(this.failMsg);
                        }
                    }
                }
            }
        }
    }
}
</script>

<style lang="scss">

</style>
